
function EscapeTimeQueue()
{
  var _pendingTasks = [];
  var _activeTasks = [];

  var _workerPool = new Array();
  _workerPool[0] = new Worker('escape_time_worker.js');

  this.addPoint = function(point, callback)
  {
    _pendingTasks.push({
      'point': point,
      'callback': callback
    });
    startPendingTasks();
  };

  this.finalize = function()
  {
    _pendingTasks = null;

    if(_activeTasks)
    {
      _activeTasks.map(function(_, i) {
        _activeTasks[i].worker.removeEventListener('message', _activeTasks[i].handler);
        _activeTasks[i].worker.terminate();
      });
    }
    _activeTasks = null;

    if(_workerPool)
    {
      _workerPool.map(function(_, i) {
        _workerPool[i].terminate();
      });
    }
    _workerPool = null;
  };

  function startPendingTasks()
  {
    var i;
    for(i = 0; i < _pendingTasks.length && _workerPool.length > 0; i++)
      startTask(_pendingTasks[i], _workerPool.pop());
    _pendingTasks = _pendingTasks.slice(i);
  }

  function startTask(task, worker)
  {
    task.worker = worker;
    task.handler = createResponseHandler(task);
    task.worker.addEventListener('message', task.handler);
    worker.postMessage(task.point);
    _activeTasks.push(task);
  }

  function createResponseHandler(task)
  {
    function responseHandler(message)
    {
      task.result = message.data;
      task.worker.removeEventListener('message', task.handler);
      removeDoneTasks();
      startPendingTasks();
    }
    return responseHandler;
  }

  function removeDoneTasks()
  {
    var i;
    for(i = 0; i < _activeTasks.length && _activeTasks[i].result !== undefined; i++)
    {
      if(_activeTasks[i].callback)
        _activeTasks[i].callback(_activeTasks[i].result);
      _workerPool.push(_activeTasks[i].worker);
    }
    _activeTasks = _activeTasks.slice(i);
  }

  return this;
}
EscapeTimeQueue.prototype = new Object();
EscapeTimeQueue.prototype.constructor = EscapeTimeQueue;
